home *** CD-ROM | disk | FTP | other *** search
- /*
- * Hull.C - methods for hull manipulations.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include <values.h>
- #include "Hull.h"
-
- //___________________________________________________________ Hull
-
- implementTable(HullSymtab, rcString, HullPtr);
-
- Hull::Hull()
- : primitives(new GeoObjectList(10))
- {}
-
- Hull::~Hull()
- {
- #ifndef OLD_STYLE_CPP
- // AT&T 2.x has problems: too compilcated pointer expression
- for (register long i=0; i<primitives->count(); i++)
- delete primitives->item(i);
- #endif
-
- delete primitives;
- }
-
- void Hull::addPrimitive(GeoObject* obj)
- {
- primitives->append(obj);
- }
-
- long Hull::numPrimitives() const
- {
- return primitives->count();
- }
-
- /*
- * Intersect ray with hull primitives and calculate closest object
- * and distance to this object.
- * intersect return TRUE if hit occured, FALSE otherwise.
- */
-
- int Hull::intersect(const Ray& ray, real& dist, GeoObject*& obj) const
- {
- int hit = FALSE;
- TransMatrix* itrans;
-
- dist = MAXFLOAT;
- obj = NULL;
-
- for (register long i=0; i<primitives->count(); i++) {
-
- /*
- * primitive has transformation matrix attached
- * -> transform the ray
- */
- if ((itrans = primitives->item(i)->getInvTrans()) != NULL) {
- Ray newRay(ray);
- real distfact = newRay.transform(*itrans);
-
- /*
- * Transformimg the ray can change the distance between the
- * ray origin and the Point of intersection. We save the amount
- * the is "stretched" and later devide the computed distance
- * by this amount.
- */
- dist *= distfact;
- if (primitives->item(i)->intersect(newRay, EPSILON*distfact, dist)) {
- obj = primitives->item(i);
- hit = TRUE;
- }
- dist /= distfact;
- }
- else {
- if (primitives->item(i)->intersect(ray, EPSILON, dist)) {
- obj = primitives->item(i);
- hit = TRUE;
- }
- }
- }
- return hit;
- }
-
- /*
- * convertToPolygonList tesselates all the primitives in the hull
- * and returns the result as a list of polygons.
- * If there is no polygon in the hull, a empty polygon list is
- * returned.
- */
-
- PolygonList* Hull::convertToPolygonList(const BoundingBox& bbox) const
- {
- PolygonList* polys = new PolygonList;
- PolygonList* polytmp;
-
- for (register long i=0; i<primitives->count(); i++) {
- if ((polytmp = primitives->item(i)->tesselate(bbox)) != NULL) {
- for (register long j=0; j<polytmp->count(); j++)
- polys->append(polytmp->item(j));
- delete polytmp;
- }
- }
-
- return polys;
- }
-